package com.qiantu.phone.ui.activity;

import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.hjq.base.BaseActivity;
import com.hjq.base.BaseAdapter;
import com.hjq.http.lifecycle.ApplicationLifecycle;
import com.hjq.http.listener.HttpCallback;
import com.hjq.toast.ToastUtils;
import com.qiantu.api.db.LLControllerDBManager;
import com.qiantu.api.db.LLDeviceDBManager;
import com.qiantu.api.db.LLFloorDBManager;
import com.qiantu.api.db.LLRoomDBManager;
import com.qiantu.api.entity.ControllerBean;
import com.qiantu.api.entity.DeviceBaseConfigInfo;
import com.qiantu.api.entity.DeviceBean;
import com.qiantu.api.entity.FloorBean;
import com.qiantu.api.entity.QueryCodeResultBean;
import com.qiantu.api.entity.QueryCodeResultListBean;
import com.qiantu.api.entity.ScanWirelessControllerBean;
import com.qiantu.api.http.LLHttpManager;
import com.qiantu.api.http.model.HttpData;
import com.qiantu.api.utils.DeviceInfoParseUtil;
import com.qiantu.api.utils.ThemeUtil;
import com.qiantu.phone.BuildConfig;
import com.qiantu.phone.R;
import com.qiantu.phone.app.AppActivity;
import com.qiantu.phone.app.AppApplication;
import com.qiantu.phone.ui.adapter.AddWirelessDeviceAdapter;
import com.qiantu.phone.ui.dialog.BottomAddDeviceEditDialog;
import com.lxj.xpopup.XPopup;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;

import static com.qiantu.api.entity.RoomBean.ROOM_COMMON_SERIALNO;

/**
 * time   : 2021/12/22
 */
public class BluetoothAddDeviceActivity extends AppActivity {

    private static final String TAG = "BluetoothAddDeviceActivity";

    private TextView tvScanTip;
    private TextView tvScanSubTip;
    private GifImageView gifImageView;
    private RecyclerView deviceRecyclerView;
    private TextView btnScanAgain;

    private AddWirelessDeviceAdapter mAddWirelessDeviceAdapter;

    private String houseSerialNo;
    private Handler mHandler = new Handler();
    //    private int totalTime = 30 * 1000;
    private GifDrawable gifDrawable;
    private long startTime;
    private List<String> scanQueryCodes = new ArrayList<>();
    private List<String> addQueryCodes = new ArrayList<>();
    List<ScanWirelessControllerBean> scanDevices = new ArrayList<>();
    private BottomAddDeviceEditDialog mBottomAddDeviceEditDialog;
    private ScanWirelessControllerBean editController;
    private int editPosition;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_bluetooth_add_device;
    }

    @Override
    protected void initView() {
        tvScanTip = findViewById(R.id.tv_scan_tip);
        tvScanSubTip = findViewById(R.id.tv_scan_sub_tip);
        gifImageView = findViewById(R.id.gif_image_view);
        btnScanAgain = findViewById(R.id.btn_scan_again);
        deviceRecyclerView = findViewById(R.id.device_recycler_view);
        deviceRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAddWirelessDeviceAdapter = new AddWirelessDeviceAdapter(this);
        mAddWirelessDeviceAdapter.setData(scanDevices);
        deviceRecyclerView.setAdapter(mAddWirelessDeviceAdapter);
        setOnClickListener(btnScanAgain);
        //预设置
        mAddWirelessDeviceAdapter.setOnChildClickListener(R.id.btn_preset, new BaseAdapter.OnChildClickListener() {
            @Override
            public void onChildClick(RecyclerView recyclerView, View childView, int position) {
                editPosition = position;
                editController = scanDevices.get(position);
                showBottomAddDeviceEditDialog(true);
            }
        });
        //添加
        mAddWirelessDeviceAdapter.setOnChildClickListener(R.id.btn_add, new BaseAdapter.OnChildClickListener() {
            @Override
            public void onChildClick(RecyclerView recyclerView, View childView, int position) {
                editPosition = position;
                editController = scanDevices.get(position);
                List<ScanWirelessControllerBean.MasterController> masterControllers = editController.getMasterControllers();
                //可选网关大于1时才去设置网关
                if (masterControllers.size() > 1) {
                    showBottomAddDeviceEditDialog(false);
                }else{
                    editController.setAddStatus(1);
                    mAddWirelessDeviceAdapter.notifyItemChanged(position);
                    addDevice(editController);
                }
            }
        });
        //重试
        mAddWirelessDeviceAdapter.setOnChildClickListener(R.id.btn_retry, new BaseAdapter.OnChildClickListener() {
            @Override
            public void onChildClick(RecyclerView recyclerView, View childView, int position) {
                ScanWirelessControllerBean scanWirelessDevice = scanDevices.get(position);
                scanWirelessDevice.setAddStatus(1);
                mAddWirelessDeviceAdapter.notifyItemChanged(position);
                addDevice(scanWirelessDevice);
            }
        });
        start();
    }

    private void showBottomAddDeviceEditDialog(boolean isPreSet) {
        if (mBottomAddDeviceEditDialog == null) {
            mBottomAddDeviceEditDialog = new BottomAddDeviceEditDialog(this);
            mBottomAddDeviceEditDialog.setDialogClickListener(new BottomAddDeviceEditDialog.DialogClickListener() {
                @Override
                public void onDeviceIconClick() {
                    mBottomAddDeviceEditDialog.hideKeyboard();
                    Intent intent = new Intent(getContext(), DeviceIconSelectActivity.class);
                    String deviceType = editController.getDeviceItems().get(0).getDeviceType();
                    DeviceBaseConfigInfo deviceBaseConfigInfo = DeviceInfoParseUtil.parseData(getContext(), deviceType, DeviceBaseConfigInfo.class);
                    intent.putExtra("type", deviceBaseConfigInfo.getType());
                    intent.putExtra("deviceType", deviceType);
                    intent.putExtra("selectIcon", editController.getDeviceItems().get(0).getImageUrl());
                    startActivityForResult(intent, new BaseActivity.OnActivityCallback() {
                        @Override
                        public void onActivityResult(int resultCode, Intent data) {
                            if (resultCode == RESULT_OK) {
                                String selectIconUrl = data.getStringExtra("DATA");
                                editController.getDeviceItems().get(0).setImageUrl(selectIconUrl);
                                mBottomAddDeviceEditDialog.setDeviceIcon(BuildConfig.APP_RESOURCE_BASE + ThemeUtil.getIconThemeSuffix() + selectIconUrl + "_on.png");
                            }
                        }
                    });
                }

                @Override
                public void onDeviceFloorRoomClick() {
                    mBottomAddDeviceEditDialog.hideKeyboard();
                    Intent intent = new Intent(getContext(), SelectFloorRoomActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    startActivityForResult(intent, new BaseActivity.OnActivityCallback() {
                        @Override
                        public void onActivityResult(int resultCode, Intent data) {
                            if (resultCode == RESULT_OK) {
                                String serialNo = data.getStringExtra("serialNo");
                                String roomName = data.getStringExtra("roomName");
                                String floorSerialNo = data.getStringExtra("floorSerialNo");
                                ScanWirelessControllerBean.DeviceItem deviceItem = editController.getDeviceItems().get(0);
                                deviceItem.setRoomSerialNo(serialNo);
                                if (ROOM_COMMON_SERIALNO.equals(serialNo)) {
                                    deviceItem.setLinkType(2);
                                } else {
                                    deviceItem.setLinkType(1);
                                }
                                FloorBean floor = null;
                                if (!TextUtils.isEmpty(floorSerialNo)) {
                                    floor = LLFloorDBManager.getInstance(getContext()).getFloorByFloorSerialNo(floorSerialNo);
                                }
                                mBottomAddDeviceEditDialog.setFloorRoom(floor == null ? roomName : floor.getFloorName() + roomName);
                            }
                        }
                    });
                }

                @Override
                public void onConfirmClick() {
                    String btnText = mBottomAddDeviceEditDialog.getBtnText();
                    //下一步
                    if (getString(R.string.common_step_next).equals(btnText)) {
                        String name = mBottomAddDeviceEditDialog.getText();
                        if (TextUtils.isEmpty(name)) {
                            toast(R.string.device_name);
                            return;
                        }
                        List<ScanWirelessControllerBean.DeviceItem> deviceItems = editController.getDeviceItems();
                        if (deviceItems.size() > 1) {
                            editController.setName(name);
                        } else if (deviceItems.size() == 1) {
                            deviceItems.get(0).setName(name);
                        }
                        List<ScanWirelessControllerBean.MasterController> masterControllers = editController.getMasterControllers();
                        mBottomAddDeviceEditDialog.showSelectGateway(masterControllers);
                    } else if (getString(R.string.finish_add).equals(btnText)) {//完成添加
                        List<ScanWirelessControllerBean.MasterController> masterControllers = editController.getMasterControllers();
                        //可选网关大于1时才去设置网关
                        if (masterControllers.size() > 1) {
                            if (mBottomAddDeviceEditDialog.getSelectedGateway() == null) {
                                ToastUtils.show(R.string.please_select_gateway);
                                return;
                            }
                            List<ScanWirelessControllerBean.MasterController> selectedMasterControllers = new ArrayList<>();
                            selectedMasterControllers.add(mBottomAddDeviceEditDialog.getSelectedGateway());
//                            //重新创建一个请求数据，为了不改变原有的可选网关数据
//                            ScanWirelessControllerBean addController = new ScanWirelessControllerBean(editController);
//                            addController.setMasterControllers(selectedMasterControllers);
                            editController.setMasterControllers(selectedMasterControllers);
                        } else {
                            String name = mBottomAddDeviceEditDialog.getText();
                            if (TextUtils.isEmpty(name)) {
                                toast(R.string.device_name);
                                return;
                            }
                            List<ScanWirelessControllerBean.DeviceItem> deviceItems = editController.getDeviceItems();
                            if (deviceItems.size() > 1) {
                                editController.setName(name);
                            } else if (deviceItems.size() == 1) {
                                deviceItems.get(0).setName(name);
                            }
                        }
                        editController.setAddStatus(1);
                        mAddWirelessDeviceAdapter.notifyItemChanged(editPosition);
                        addDevice(editController);
                        mBottomAddDeviceEditDialog.dismiss();
                    }
                }
            });
            new XPopup.Builder(this)
                    .dismissOnBackPressed(true)
                    .enableDrag(true)
                    .asCustom(mBottomAddDeviceEditDialog);
        }
        mBottomAddDeviceEditDialog.setFirstStep();
        List<ScanWirelessControllerBean.DeviceItem> deviceItems = editController.getDeviceItems();
        if (deviceItems.size() > 1) {
            mBottomAddDeviceEditDialog.setAddDeviceType(1);
            mBottomAddDeviceEditDialog.setDeviceName(editController.getName());
        } else if (deviceItems.size() == 1) {
            ScanWirelessControllerBean.DeviceItem deviceItem = deviceItems.get(0);
            mBottomAddDeviceEditDialog.setAddDeviceType(0);
            mBottomAddDeviceEditDialog.setDeviceName(deviceItem.getName());
            mBottomAddDeviceEditDialog.setDeviceIcon(BuildConfig.APP_RESOURCE_BASE + ThemeUtil.getIconThemeSuffix() + deviceItem.getImageUrl() + "_on.png");
            mBottomAddDeviceEditDialog.setFloorRoom(LLRoomDBManager.getInstance(getContext()).getFloorRoomName(deviceItem.getRoomSerialNo()));
        }
        List<ScanWirelessControllerBean.MasterController> masterControllers = editController.getMasterControllers();
        if(isPreSet){
            if(masterControllers.size() > 1){
                mBottomAddDeviceEditDialog.setBtnText(getString(R.string.common_step_next));
            }else{
                mBottomAddDeviceEditDialog.setBtnText(getString(R.string.finish_add));
            }
        }else{
            mBottomAddDeviceEditDialog.showSelectGateway(masterControllers);
        }
        mBottomAddDeviceEditDialog.show();
    }

    @Override
    protected void initData() {

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_scan_again:
                start();
                break;
        }
    }

    private void start() {
//        startTime = System.currentTimeMillis();
//        post(countRunnable);
        if (gifDrawable == null) {
            try {
                int id = AppApplication.getInstance().getResourceId("gif_add_device_automaticfind" + (TextUtils.isEmpty(ThemeUtil.getIconThemeSuffix()) ? "" : "_") + ThemeUtil.getIconThemeSuffix().replace("/", ""), "drawable");
                gifDrawable = new GifDrawable(getResources(), id);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        gifDrawable.reset();
        tvScanTip.setText(R.string.auto_scan);
        gifImageView.setImageDrawable(gifDrawable);
        btnScanAgain.setVisibility(View.GONE);
        houseSerialNo = AppApplication.getInstance().getCurHouseInfo().getHouseSerialNo();
        startScan();
    }

//    private Runnable countRunnable = new Runnable() {
//        @Override
//        public void run() {
//            if(System.currentTimeMillis() - startTime > totalTime){
//                showFailed();
//            }else{
//                postDelayed(this, 990);
//            }
//        }
//    };

    private void startScan() {
        LLHttpManager.scanBluetoothDevice(this, houseSerialNo, new HttpCallback<HttpData<QueryCodeResultListBean<Object, List<ScanWirelessControllerBean>>>>(this) {
            @Override
            public void onStart(Call call) {

            }

            @Override
            public void onSucceed(HttpData<QueryCodeResultListBean<Object, List<ScanWirelessControllerBean>>> result) {
                handleScanResult(result.getData().getAsyncQueryResList());
            }

            @Override
            public void onFail(Exception e) {
                showFailed();
            }

            @Override
            public void onEnd(Call call) {

            }
        });
    }

    private void queryScan() {
        LLHttpManager.queryScanBluetooth(this, scanQueryCodes, new HttpCallback<HttpData<QueryCodeResultListBean<Object, List<ScanWirelessControllerBean>>>>(this) {
            @Override
            public void onStart(Call call) {

            }

            @Override
            public void onSucceed(HttpData<QueryCodeResultListBean<Object, List<ScanWirelessControllerBean>>> result) {
                handleScanResult(result.getData().getAsyncQueryResList());
            }

            @Override
            public void onFail(Exception e) {
                showFailed();
            }

            @Override
            public void onEnd(Call call) {

            }
        });
    }

    private void stopScan() {
        LLHttpManager.stopScanBluetoothDevice(new ApplicationLifecycle(), scanQueryCodes, new HttpCallback<HttpData<QueryCodeResultListBean<Object, List<ScanWirelessControllerBean>>>>(this) {
            @Override
            public void onStart(Call call) {

            }

            @Override
            public void onSucceed(HttpData<QueryCodeResultListBean<Object, List<ScanWirelessControllerBean>>> result) {
            }

            @Override
            public void onFail(Exception e) {

            }

            @Override
            public void onEnd(Call call) {

            }
        });
    }

    private void handleScanResult(List<QueryCodeResultBean<Object, List<ScanWirelessControllerBean>>> datas) {
        if (datas == null) {
            return;
        }
        boolean needQuery = false;
        boolean isSuccess = false;
        List<String> queryCodes = new ArrayList<>();
        for (QueryCodeResultBean<Object, List<ScanWirelessControllerBean>> resultBean : datas) {
            int queryStateType = resultBean.getQueryStateType();
            //发起操作:0 正在操作:1 操作成功:2 操作失败:3 操作异常:4 停止操作:5
            if (queryStateType == 0 || queryStateType == 1) {
                queryCodes.add(resultBean.getQueryCode());
                needQuery = true;
            } else if (queryStateType == 2 && resultBean.getRspData() != null) {
                isSuccess = true;
                List<ScanWirelessControllerBean> scanWirelessControllers = resultBean.getRspData();
                addAndUpdateScanWirelessController(scanWirelessControllers);
            }
        }
        scanQueryCodes = queryCodes;
        if (needQuery) {
            postScanQuery();
        } else {
            tvScanTip.setText(R.string.scan_again);
            btnScanAgain.setVisibility(View.VISIBLE);
            gifDrawable.stop();
        }
        if (isSuccess) {
            tvScanSubTip.setText(getString(R.string.scanned_devices_count_hint, scanDevices.size()));
            mAddWirelessDeviceAdapter.notifyDataSetChanged();
        }
    }

    private void addAndUpdateScanWirelessController(List<ScanWirelessControllerBean> newScanWirelessControllers) {
        if (scanDevices.size() == 0) {
            scanDevices.addAll(newScanWirelessControllers);
        } else {
            List<ScanWirelessControllerBean> notContainsScanWirelessControllers = new ArrayList<>();
            for (ScanWirelessControllerBean newScanWirelessController : newScanWirelessControllers) {
                boolean isContains = false;
                for (ScanWirelessControllerBean oldScanWirelessController : scanDevices) {
                    if (oldScanWirelessController.getDeviceSn().equals(newScanWirelessController.getDeviceSn())) {
                        isContains = true;
                        List<ScanWirelessControllerBean.MasterController> newMasterControllers = newScanWirelessController.getMasterControllers();
                        List<ScanWirelessControllerBean.MasterController> oldMasterControllers = oldScanWirelessController.getMasterControllers();
                        mergeMasterControllers(newMasterControllers, oldMasterControllers);
                        break;
                    }
                }
                if(!isContains){
                    notContainsScanWirelessControllers.add(newScanWirelessController);
                }
            }
            if(notContainsScanWirelessControllers.size() > 0){
                scanDevices.addAll(notContainsScanWirelessControllers);
            }
        }
    }

    private void mergeMasterControllers(List<ScanWirelessControllerBean.MasterController> newMasterControllers, List<ScanWirelessControllerBean.MasterController> oldMasterControllers) {
        List<ScanWirelessControllerBean.MasterController> notContainsMasterControllers = new ArrayList<>();
        for (ScanWirelessControllerBean.MasterController newMasterController : newMasterControllers) {
            boolean isContains = false;
            for (ScanWirelessControllerBean.MasterController oldMasterController : oldMasterControllers) {
                if (oldMasterController.getControllerSerialNo().equals(newMasterController.getControllerSerialNo())) {
                    isContains = true;
                    break;
                }
            }
            if(!isContains){
                notContainsMasterControllers.add(newMasterController);
            }
        }
        if(notContainsMasterControllers.size() > 0){
            oldMasterControllers.addAll(notContainsMasterControllers);
        }
    }

    private void postScanQuery() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                queryScan();
            }
        }, 1000);
    }

    private void postAddQuery() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                queryAddDevice();
            }
        }, 1000);
    }

    private void showFailed() {
        tvScanTip.setText(R.string.scan_again);
        tvScanSubTip.setText(getString(R.string.scanned_devices_count_hint, 0));
        btnScanAgain.setVisibility(View.VISIBLE);
        mHandler.removeCallbacksAndMessages(null);
        gifDrawable.stop();
    }

    private void addDevice(ScanWirelessControllerBean wirelessDevice) {
        List<ScanWirelessControllerBean> data = new ArrayList<>();
        data.add(wirelessDevice);
        LLHttpManager.addBluetoothDevice(this, data, new HttpCallback<HttpData<QueryCodeResultListBean<String, String>>>(this) {
            @Override
            public void onStart(Call call) {

            }

            @Override
            public void onSucceed(HttpData<QueryCodeResultListBean<String, String>> result) {
                handleAddResult(result.getData().getAsyncQueryResList());
            }

            @Override
            public void onFail(Exception e) {
                showFailed();
            }

            @Override
            public void onEnd(Call call) {

            }
        });
    }

    private void queryAddDevice() {
        LLHttpManager.queryAddBluetooth(this, addQueryCodes, new HttpCallback<HttpData<QueryCodeResultListBean<String, String>>>(this) {
            @Override
            public void onStart(Call call) {

            }

            @Override
            public void onSucceed(HttpData<QueryCodeResultListBean<String, String>> result) {
                handleAddResult(result.getData().getAsyncQueryResList());
            }

            @Override
            public void onFail(Exception e) {
                showFailed();
            }

            @Override
            public void onEnd(Call call) {

            }
        });
    }


    private void handleAddResult(List<QueryCodeResultBean<String, String>> queryResList) {
        if (queryResList == null) {
            return;
        }
        boolean needQuery = false;
        boolean needUpdate = false;
        addQueryCodes.clear();
        for (QueryCodeResultBean<String, String> resultBean : queryResList) {
            int queryStateType = resultBean.getQueryStateType();
            //发起操作:0 正在操作:1 操作成功:2 操作失败:3 操作异常:4 停止操作:5
            if (queryStateType == 0 || queryStateType == 1) {
                addQueryCodes.add(resultBean.getQueryCode());
                needQuery = true;
            } else if (queryStateType == 2 && resultBean.getRspData() != null) {
                needUpdate = true;
                String deviceSn = resultBean.getRspData();
                for (ScanWirelessControllerBean scanWirelessDevice : scanDevices) {
                    if (scanWirelessDevice.getDeviceSn().equals(deviceSn)) {
                        scanWirelessDevice.setAddStatus(2);//添加成功
                        refreshControllerData(AppApplication.getInstance().getCurrentHouseSerialNo());
                        refreshDeviceData(AppApplication.getInstance().getCurrentHouseSerialNo());
                        break;
                    }
                }
            } else if ((queryStateType == 3 || queryStateType == 4) && resultBean.getRspData() != null) {
                needUpdate = true;
                String deviceSn = resultBean.getRspData();
                for (ScanWirelessControllerBean scanWirelessDevice : scanDevices) {
                    if (scanWirelessDevice.getDeviceSn().equals(deviceSn)) {
                        scanWirelessDevice.setAddStatus(3);//添加失败
                        break;
                    }
                }
            }
        }
        if (needQuery) {
            postAddQuery();
        }
        if (needUpdate) {
            mAddWirelessDeviceAdapter.notifyDataSetChanged();
        }
    }

    private void refreshControllerData(String houseSerialNo) {
        LLHttpManager.getControllers(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<ControllerBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<ControllerBean>> result) {

                LLControllerDBManager.getInstance(getContext()).refreshAllControllersTx(result.getData());
            }

            @Override
            public void onFail(Exception e) {
            }
        });
    }

    private void refreshDeviceData(String houseSerialNo) {
        LLHttpManager.house_getdevices(new ApplicationLifecycle(), houseSerialNo, new HttpCallback<HttpData<List<DeviceBean>>>(this) {
            @Override
            public void onSucceed(HttpData<List<DeviceBean>> result) {
                LLDeviceDBManager.getInstance(getContext()).refreshAllDevicesTx(result.getData(), null);
            }

            @Override
            public void onFail(Exception e) {
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopScan();
        mHandler.removeCallbacksAndMessages(null);
        if (gifDrawable != null) {
            gifDrawable.recycle();
        }
    }
}